//
// Created by admin on 2017/6/27.
//

#ifndef UNTITLED4_VI_H
#define UNTITLED4_VI_H
void prints(char *text);
void log(char *text);
void logi(char *statement, int intValue);

void show_text_same(char *text, int line_number);
int show_text(char *text[], int *line_number, int max_len, int mode);
char **readFile(int fd, int buf_size, int text_num, int text_length, int max_len, int *line_number);
char *strcat_n(char *des, char *src, int len, int max_len);
char *strcat2(char *des, char *src, int max_len);
char *blank_same_cpy(int before, int row, int col, int max_length);
void drawCursor(int *line_number, int row, int col, char **pString);
int wait_for_input(char *text[], int row, int col, int *line_number, int mode, int max_len);
void only_show_text(char *text[], int row, int col, int *line_number);

int judgeArg(int type);
int isArgLegal(int argc, char *argv[]);
int isFileLegal(int fd, int type);
int judgeFile(int type);
char *malloc1DimensionalChar(int size);
char **malloc2DimensionalChar(int size1, int size2);

void cursorNext(int rowOrCol, int *line_number, char **text, int i, int type, int event);
void moveCursor(int rowOrCol, int type, int *line_number, char **text, int addOrSub, int event);
void cursorColToRow(int type, int *pInt, char **pString, int i, int event);
int setPage(int max_row);

int getCurrentMaxLengthLabel(char **text);
int getCurrentMaxLength(char **text);
void initGlobal();
char *itoa2(int a);
void addLogPrintStr(char *str);
int getMaxLength(char **text, int row);
int draw(char *text[], int *line_number, int max_len, int mode);
int getMaxLengthLabel(char **text, int row);
void insertCharInside(char **text, int ch, int *line_number, int row, int col);
void insertChar(char **text, int ch, int *line_number, int row, int col);
void clearScreen();
void createNewTextLine(char **text, int *line_number);
int deleteCharInside(char **text, int row, int col, int *line_number);
void deleteChar(char **text, int *line_number, int row, int col);
char *trim(char *text);
void clearCommandKeyFlag();
int hasStateWrite();
int resolveSuspendMode(int ch);
int hasPressEsc();
int hasPressColon();
int isCharCommandLegal(int i);
void clearCommandText();
int resolveCommandTextMode(int chValue, char *pString[], int *line_number, int max_len);
int resolveInsertMode(char *text[], int row, int col, int *line_number, int chValue, int max_len);
int resolveCommandMode(int chValue);
int beforeCommandTextMode(int ch);
int beforeInsertMode();
int beforeCommandMode();
int beforeSuspendMode();
void writeFile(char **text, int line);
void writeIntoFile(char *const *text, const int *line_number);
int isKeyToCommondText(char ch);
int findSubStringDownMove(char *const *text, const char *command, int start_row, int end_row, int start_col, int end_col);
void setMissKey(int arrogantKey, int ch);
int
findSubStringLoopInside(const char *command, char *const *text, int start_row, int begin_index, int end_index, int label);
void findStrDown(char *const *text, const int *line_number, const char *command);
void findStrUp(char *const *text, const int *line_number, const char *command);
void feedChar(char **text, int *line_number);
// 将二维数组指针，从第i行开始，往上方向移动1行
void moveLineUp(char **text, int *line_number, int beginRow, int max_len);
void pageDown(int *line_number);
void pageUp(int *line_number);
int calculatePos(int row, int rowShitf, int col, int colShift);
void exitNow();
int putsText(char *text, int len, int current_row, int current_col);
int putsSameText(int ch, int len, int current_row, int current_col, int col_shift);
void initDrawRuler();
void drawWindow(char *const *text, const int *line_number, int j, int current_col, int startIndex);
void initCursor();

void initShouldDo();

void initCommand();


enum MAX {
    MAX_LINE_NUMBER = 256,
    MAX_LINE_INIT_LIMIT = 77,
    MAX_LINE_SHOW_LIMIT = 73,
    MAX_ROW_LIMIT = 24,
    MAX_OCCUPY_LIMIT = 4
};
enum SET {
    SET_ROW = 0x101,
    SET_COL = 0x102
};
enum FileRead {
    O_RDONLY = 0x000,
    O_WRONLY = 0x001,
    O_RDWR = 0x002,
    O_CREATE = 0x200
};
enum OPERATION {
    ADD = 0x4001,
    SUB = 0X4002
};
enum KEY {
    KEY_CURSOR = 1,
    KEY_UP = -30,
    KEY_DOWN = -29,
    KEY_LEFT = -28,
    KEY_RIGHT = -27,
    KEY_ESC = 27,
    KEY_END = -31,
    KEY_HOME = -32,
    KEY_BACK_SPACE = 8,
    KEY_ENTER = 0,
    KEY_DELETE = -23,
    KEY_INSERT = -24,
    KEY_COLON = 58,
    KEY_LINE_FEED = 13,
    KEY_LOWER_i = 105,
    KEY_LOWER_n = 110,
    KEY_UPPER_N = 78,
    KEY_DIV = 47,
    KEY_PAGE_UP = -26,
    KEY_PAGE_DOWN = -25,
    KEY_SPACE = 32,
    KEY_QUESTION_MARK = 63,
    KEY_CTRL_A = 1,
    KEY_CTRL_E = 5
};
enum FLAG {
    FLAG_CLEAR = 0x0,
    FLAG_STATE_HAS_WRITE = 0x1 << 0,
    FLAG_KEY_HAS_PRESS_ESC = 0x1 << 0,
    FLAG_KEY_HAS_PRESS_COLON = 0x1 << 1
};
enum RESULT {
    SUCESS = 0,
    FAIL = 1
};
enum MODE {
    MODE_COMMAND = 0x200,
    MODE_COMMAND_TEXT = 0x201,
    MODE_INSERT = 0x210,
    MODE_SUSPEND = 0x220

};
enum EVENT {
    EVENT_INSERT = 0x101,
    EVENT_DELETE = 0x102,
    EVENT_DELETE_STAY = 0x1021,
    EVENT_DELETE_MOVE = 0x1022
};
enum FileStatus {
    FILE_LEGAL, FILE_OPEN_FAIL, FILE_CREATE_FAIL
};

enum ArgStatus {
    ARG_LEGAL, ARG_DEFICIENCY
};

struct ShouldDo {
    int should_show_log;
    int should_clear_log;
    int should_refresh_screen;
    int should_force_refresh_screen;
    int should_force_miss_key;
    int should_force_draw;
    int should_miss_draw;
};

struct Command {
    char *COMMAND_QUIT;
    char *COMMAND_QUIT_FORCE;
    char *COMMAND_WRITE;
    char *COMMAND_WRITE_QUIT;
};
struct DrawRuler {
    int startRow;
    int endRow;
    int flag;
};
struct Cursor {
    int row;
    int col;
};
#endif //UNTITLED4_VI_H
